Add Playwright E2E suite; fix work-entry date persistence and cascade delete - #917
devin-ai-integration[bot] wants to merge 1 commit into
Conversation
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
|
E2E verification — Playwright suite + manual GUI runRan the new Playwright suite headlessly and manually drove the app in Chrome against a local backend ( Playwright: CSV export date fix — Date column is now YYYY-MM-DD, not epoch millisThe Work Entries and Reports tables also render Reports totals recompute correctlyOne 4.5h entry → Client delete cascades to work entries (PRAGMA foreign_keys = ON)Deleting the client removed both of its work entries — no orphan rows, no errors. Other flows verified
|






Summary
New
e2e/Playwright project (20 tests, all passing) covering login, client CRUD, the work-entry lifecycle, report totals + CSV export, and input edge cases. Tests run against the real backend/frontend —playwright.config.tsbootsbackend(3001) andfrontend(5173) viawebServerand reuses already-running servers.Two application bugs the suite surfaced, plus one testability change:
Work-entry dates were persisted as epoch millis.
Joi.date().iso()coercesdateto aDate, which sqlite3 binds as a number, so the API and the CSV/PDF exports returned1786320000000instead of2026-08-10:workEntries.jsnow normalizes to a calendar day (toDateOnly) on insert and update. Covered by the CSV export assertion inreports.spec.ts.ON DELETE CASCADEwas never enforced — sqlite defaultsforeign_keysoff, so deleting a client left orphanedwork_entriesrows (invisible in listings only because the list query INNER JOINsclients).initializeDatabasenow runsPRAGMA foreign_keys = ON.Rate limit is configurable via
RATE_LIMIT_MAX/RATE_LIMIT_WINDOW_MS(defaults unchanged at 100 / 15 min). The global 100-requests-per-IP limit throttles a full suite run, so the E2EwebServerraises it.Test isolation comes from the app's own model: each test logs in with a unique email, and all data is scoped by
user_email, so no cleanup is needed against the in-memory DB.Backend unit tests (161) and the frontend lint/build still pass.
Link to Devin session: https://partner-workshops.devinenterprise.com/sessions/7790300b33bf44b7b56f9a98100e185c